/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Blocos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraConst;
import analiseSintatica.Regras.Declaracoes.RegraDeclaracao;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraPrototipo;
import analiseSintatica.Regras.DeclaracoesIniciais.RegraTypedef;
import analiseSintatica.Regras.Funcao.RegraFuncao;
import analiseSintatica.Regras.Regra;

import java.util.LinkedList;

/**
 *
 * @author anderson
 * @date  6:30:10 PM
 */
public class RegraDeclsInicial extends Regra {

    protected static Regra instancia;

    protected String estrutura = "{<typedef> | <const> | <funcao> | <declaracao>}";
    
    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraDeclsInicial(){
        
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraDeclsInicial getInstance() {
        if (instancia == null) {
            instancia = new RegraDeclsInicial();
        }
        return (RegraDeclsInicial) instancia;

    }


    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{
        
    	while (listaContem(RegraTypedef.getInstance().getPrimeiro(), listaTokens.getFirst())||
        		listaContem(RegraConst.getInstance().getPrimeiro(), listaTokens.getFirst())||
        		(listaContem(RegraPrototipo.getInstance().getPrimeiro(), listaTokens.getFirst()) &&
        				listaTokens.get(1).getToken().equals("identificador") &&
        				listaTokens.get(2).getLexema().equals("(")) ||
				listaContem(RegraDeclaracao.getInstance().getPrimeiro(), listaTokens.getFirst())
                ){

            if(listaContem(RegraTypedef.getInstance().getPrimeiro(), listaTokens.getFirst())){
            	RegraTypedef.getInstance().analisar(listaTokens);
            }else if(listaContem(RegraConst.getInstance().getPrimeiro(), listaTokens.getFirst())){
            	RegraConst.getInstance().analisar(listaTokens);
            }else if(listaContem(RegraPrototipo.getInstance().getPrimeiro(), listaTokens.getFirst()) &&
    				listaTokens.get(1).getToken().equals("identificador") &&
    				listaTokens.get(2).getLexema().equals("(")){
	    		RegraFuncao.getInstance().analisar(listaTokens);
            }
            else{
        		RegraDeclaracao.getInstance().analisar(listaTokens);

            }
        }
        return null;

    }



    @Override
    protected void setPrimeiro() {
    	this.primeiro = RegraTypedef.getInstance().getPrimeiro();
    	this.primeiro = getUniao(primeiro, RegraConst.getInstance().getPrimeiro());
    	this.primeiro = getUniao(primeiro, RegraFuncao.getInstance().getPrimeiro());
    	this.primeiro = getUniao(primeiro, RegraDeclaracao.getInstance().getPrimeiro());
    	this.primeiro = getUniao(primeiro, "e");
    }
}
